package usuario;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import java.util.ArrayList;
import java.util.List;

import junit.framework.Assert;
import model.Publicacion.Pregunta;
import model.Publicacion.Publicacion;
import model.Publicacion.Respuesta;
import model.Usuario.UsuarioSimple;
import model.insigniaYlogros.InsigniaSimple;
import model.sistema.Sistema;
import model.votoYfav.Favorito;
import model.votoYfav.Voto;

import org.joda.time.DateTime;
import org.junit.Before;
import org.junit.Test;

public class TestUsuarioSimple {
	
	Sistema sistema;
	UsuarioSimple usuarioSimple;
	UsuarioSimple usuarioSimple2;
	Pregunta p1;
	Pregunta p2;
	Respuesta r1;
	Respuesta r2;
	Voto v1;
	Voto v2;
	Voto v3;
	InsigniaSimple i;
	Favorito f;
	
	@Before
	public void setUp(){
		
		p1 = mock(Pregunta.class);
		p2 = mock(Pregunta.class);
		r1 = mock(Respuesta.class);
		r2 = mock(Respuesta.class);
		sistema = mock(Sistema.class);
		usuarioSimple = new UsuarioSimple(sistema, "nombre", "email", "nombreUsuario");
		usuarioSimple2 = new UsuarioSimple(sistema, "nombre2", "email2", "nombreUsuario2"); 
		v1 = mock(Voto.class);
		v2 = mock(Voto.class);
		v3 = mock(Voto.class);
		i = mock(InsigniaSimple.class);
		f = mock(Favorito.class);
	}
	
	@Test
	public void TestPuntajePorActividad(){
		
		usuarioSimple.hacerPregunta(p1);
		assertEquals(10, usuarioSimple.puntajePorActividad(),1);
		usuarioSimple.responderApregunta(p1, r1);
		assertEquals(15, usuarioSimple.puntajePorActividad(),1);
		usuarioSimple.hacerPregunta(p2);
		assertEquals(25, usuarioSimple.puntajePorActividad(),1);
	}

	@Test
	public void TestFactorDeRegularidad(){
		
		DateTime mesUno = new DateTime(DateTime.now().getYear(),DateTime.now().getMonthOfYear()-6,1,1,1);
		DateTime mesDos = new DateTime(DateTime.now().getYear(),DateTime.now().getMonthOfYear()-5,1,1,1);
		DateTime mesTres = new DateTime(DateTime.now().getYear(),DateTime.now().getMonthOfYear()-4,1,1,1);
		DateTime mesCuatro = new DateTime(DateTime.now().getYear(),DateTime.now().getMonthOfYear()-3,1,1,1);
		DateTime mesCinco = new DateTime(DateTime.now().getYear(),DateTime.now().getMonthOfYear()-2,1,1,1);
		DateTime mesSeis = new DateTime(DateTime.now().getYear(),DateTime.now().getMonthOfYear()-1,1,1,1);
		DateTime mesSiete = new DateTime(DateTime.now().getYear(),DateTime.now().getMonthOfYear()-0,1,1,1);
		
		Pregunta p1 = mock(Pregunta.class);
		Pregunta p2 = mock(Pregunta.class);
		Respuesta r1 = mock(Respuesta.class);
		Respuesta r2 = mock(Respuesta.class);
		Respuesta r3 = mock(Respuesta.class);
		Respuesta r4 = mock(Respuesta.class);
		Respuesta r5 = mock(Respuesta.class);
		
		
		when(p1.getFecha()).thenReturn(mesUno);
		when(p2.getFecha()).thenReturn(mesDos);
		when(r1.getFecha()).thenReturn(mesTres);
		when(r2.getFecha()).thenReturn(mesCuatro);
		when(r3.getFecha()).thenReturn(mesCinco);
		when(r4.getFecha()).thenReturn(mesSeis);
		when(r5.getFecha()).thenReturn(mesSiete);
		
		
		usuarioSimple.hacerPregunta(p1);
		usuarioSimple.hacerPregunta(p2);
		usuarioSimple.responderApregunta(p1, r1);
		usuarioSimple.responderApregunta(p1, r2);
		usuarioSimple.responderApregunta(p1, r3);
		usuarioSimple.responderApregunta(p1, r4);
		usuarioSimple.responderApregunta(p1, r5);
	
		
		
	    assertEquals(1, usuarioSimple.factorDeRegularidad(),0.01);
		
		
		
	}
	

	@Test
	public void TestGet(){
		
		
        assertEquals("nombreUsuario",usuarioSimple.getNombreUsuario());
		List<Publicacion> pubs=new ArrayList<Publicacion>();
		pubs.add(p1);
		pubs.add(r1);
		
         usuarioSimple.hacerPregunta(p1);
         usuarioSimple.responderApregunta(p1, r1);
         
         assertEquals(1,usuarioSimple.cantidadDePreguntas());
         assertEquals(1,usuarioSimple.cantidadDeRespuestas());
		assertEquals(2,usuarioSimple.cantidadDePublicaciones());
         assertEquals(pubs, usuarioSimple.getPublicaciones());
         List<Pregunta> pregs=new ArrayList<Pregunta>();
 		 pregs.add(p1);
 		List<Respuesta>res =new ArrayList<Respuesta>();
		res.add(r1);
 		assertEquals(pregs, usuarioSimple.getPreguntas());
 		assertEquals(res, usuarioSimple.getRespuestas());
 		assertEquals("email", usuarioSimple.getEmail());
 		assertEquals("nombre", usuarioSimple.getNombre());
 		assertEquals(DateTime.now().getDayOfMonth(), usuarioSimple.getFecha().getDayOfMonth());
 		assertEquals(DateTime.now().getMonthOfYear(), usuarioSimple.getFecha().getMonthOfYear());
 
 		
 		usuarioSimple.borrarPregunta(p1);
 		verify(p1,times(1)).eliminar();
 		when(p1.estaEliminada()).thenReturn(true);
 		assertTrue(p1.estaEliminada());
 		
         assertEquals(0,usuarioSimple.cantidadDePreguntas());
         assertEquals(1,usuarioSimple.cantidadDeRespuestas());
		assertEquals(1,usuarioSimple.cantidadDePublicaciones());
 		
 		
		
	}
	
	@Test
	public void TestCantidadDeVotosPositivos(){
		
		
		when(v1.aFavor()).thenReturn(true);
		when(v2.aFavor()).thenReturn(false);
		when(v3.aFavor()).thenReturn(true);
		assertEquals(0,usuarioSimple.cantidadDeVotosPositivos());
		usuarioSimple.votarPublicacion(p1, v1);
		assertEquals(1,usuarioSimple.cantidadDeVotosPositivos());
		usuarioSimple.votarPublicacion(p1, v2);
		assertEquals(1,usuarioSimple.cantidadDeVotosPositivos());
		usuarioSimple.votarPublicacion(p1, v3);
		assertEquals(2,usuarioSimple.cantidadDeVotosPositivos());
		assertEquals(3,usuarioSimple.cantDeVotos());
		usuarioSimple.sacarVoto(p1);
		verify(p1,times(1)).sacarVotoDe(usuarioSimple);
	}
	
	
	@Test
	public void TestCantidadDeVotosNegativos(){
		
		when(v1.aFavor()).thenReturn(false);
		when(v2.aFavor()).thenReturn(true);
		when(v3.aFavor()).thenReturn(false);
		assertEquals(0,usuarioSimple.cantidadDeVotosNegativos());
		usuarioSimple.votarPublicacion(p1, v1);
		assertEquals(1,usuarioSimple.cantidadDeVotosNegativos());
		usuarioSimple.votarPublicacion(p1, v2);
		assertEquals(1,usuarioSimple.cantidadDeVotosNegativos());
		usuarioSimple.votarPublicacion(p1, v3);
		assertEquals(2,usuarioSimple.cantidadDeVotosNegativos());
		assertEquals(3,usuarioSimple.cantDeVotos());
		
		
	}

	
	@Test
	public void TetsPonerFavorito(){
		
		
		assertEquals(0,usuarioSimple.cantidadDeFavoritos());
		usuarioSimple.ponerFavorito(p1);
		assertEquals(1,usuarioSimple.cantidadDeFavoritos());
		usuarioSimple.ponerFavorito(p2);
		assertEquals(2,usuarioSimple.cantidadDeFavoritos());
		
		
	}
	
	@Test
	public void TetsSacarrFavorito(){
		
		
		assertEquals(0,usuarioSimple.cantidadDeFavoritos());
		usuarioSimple.ponerFavorito(p1);
		assertEquals(1,usuarioSimple.cantidadDeFavoritos());
		usuarioSimple.ponerFavorito(p2);
		assertEquals(2,usuarioSimple.cantidadDeFavoritos());
		usuarioSimple.sacarFavorito(p1);
		verify(p1,times(1)).sacarFavoritoDe(usuarioSimple);
		
		
		
	}
	
	
	
	

	
	
	@Test
	public void TestBorrarRespuesta(){
		
		usuarioSimple.hacerPregunta(p1);
		usuarioSimple.responderApregunta(p1, r1);
		assertEquals(1,usuarioSimple.cantidadDeRespuestas());
		usuarioSimple.borrarRespuesta(r1);
		when(r1.estaEliminada()).thenReturn(true);
		assertEquals(0,usuarioSimple.cantidadDeRespuestas());
		
		
	}
	
	@Test 
	public void TestRanking(){
		DateTime mesUno = new DateTime(DateTime.now().getYear(),DateTime.now().getMonthOfYear()-6,1,1,1);
		when(p1.getFecha()).thenReturn(mesUno);
		when(p2.getFecha()).thenReturn(mesUno);
		when(r1.getFecha()).thenReturn(mesUno);
		assertEquals(0,usuarioSimple.ranking(),0);
		usuarioSimple.hacerPregunta(p1);
		usuarioSimple.responderApregunta(p1, r1);
		usuarioSimple.hacerPregunta(p2);
		assertEquals(25, usuarioSimple.ranking(),1);


		
	}
	
		
	@Test
	public void TestNoContieneInsignia(){
		
		
		
		
		assertTrue(usuarioSimple.noContieneInsignia(i));
		usuarioSimple.agregarInsignia(i);
		assertFalse(usuarioSimple.noContieneInsignia(i));
		
		
	}
	
	@Test
	public void TestLogrosFaltantesPara(){
		
		usuarioSimple.logrosFaltantesPara(i);
		verify(i,times(1)).getLogrosRestantePara(usuarioSimple);
		
		
	}
	
	@Test
	public void TestLogrosConseguidosPara(){
		
		usuarioSimple.logrosConseguidosPara(i);
		verify(i,times(1)).getLogrosConseguidosPara(usuarioSimple);
		
		
		
	}
	

}




